package context

import (
	"context"

	"github.com/bytedance/gopkg/cloud/metainfo"
)

const (
	// MetaInfo键名定义
	TenantKey            = "tenant_id"
	UserIDKey            = "user_id"
	RequestIDKey         = "request_id"
	MerchantIDKey        = "merchant_id"
	TenantIsolationKey   = "tenant_isolation"
	MerchantIsolationKey = "merchant_isolation"
)

// InjectContextToMeta 将上下文信息注入到Kitex的MetaInfo中，用于RPC调用间传递
func InjectContextToMeta(ctx context.Context) context.Context {
	// 注入租户ID
	if tenantID := GetTenantFromContext(ctx); tenantID != "" {
		ctx = metainfo.WithValue(ctx, TenantKey, tenantID)
	}

	// 注入用户ID
	if userID := GetUserIDFromContext(ctx); userID != "" {
		ctx = metainfo.WithValue(ctx, UserIDKey, userID)
	}

	// 注入请求ID
	if requestID := GetRequestIDFromContext(ctx); requestID != "" {
		ctx = metainfo.WithValue(ctx, RequestIDKey, requestID)
	}

	// 注入商户ID
	if merchantID := GetMerchantIDFromContext(ctx); merchantID != "" {
		ctx = metainfo.WithValue(ctx, MerchantIDKey, merchantID)
	}

	// 注入租户隔离设置
	if !IsTenantIsolationEnabled(ctx) {
		ctx = metainfo.WithValue(ctx, TenantIsolationKey, "false")
	}

	// 注入商户隔离设置
	if !IsMerchantIsolationEnabled(ctx) {
		ctx = metainfo.WithValue(ctx, MerchantIsolationKey, "false")
	}

	return ctx
}

// ExtractContextFromMeta 从Kitex的MetaInfo中提取上下文信息
func ExtractContextFromMeta(ctx context.Context) context.Context {
	// 提取租户ID
	if tenantID, ok := metainfo.GetValue(ctx, TenantKey); ok && tenantID != "" {
		ctx = WithTenant(ctx, tenantID)
	}

	// 提取用户ID
	if userID, ok := metainfo.GetValue(ctx, UserIDKey); ok && userID != "" {
		ctx = WithUserID(ctx, userID)
	}

	// 提取请求ID
	if requestID, ok := metainfo.GetValue(ctx, RequestIDKey); ok && requestID != "" {
		ctx = WithRequestID(ctx, requestID)
	}

	// 提取商户ID
	if merchantID, ok := metainfo.GetValue(ctx, MerchantIDKey); ok && merchantID != "" {
		ctx = WithMerchantID(ctx, merchantID)
	}

	// 提取租户隔离设置
	if isolation, ok := metainfo.GetValue(ctx, TenantIsolationKey); ok && isolation == "false" {
		ctx = WithTenantIsolation(ctx, false)
	}

	// 提取商户隔离设置
	if isolation, ok := metainfo.GetValue(ctx, MerchantIsolationKey); ok && isolation == "false" {
		ctx = WithMerchantIsolation(ctx, false)
	}

	return ctx
}

// WithMetaInfoClient 将上下文信息注入到客户端RPC调用的MetaInfo中
func WithMetaInfoClient(ctx context.Context) context.Context {
	return InjectContextToMeta(ctx)
}

// WithMetaInfoServer 从服务端RPC调用的MetaInfo中提取上下文信息
func WithMetaInfoServer(ctx context.Context) context.Context {
	return ExtractContextFromMeta(ctx)
}
